import re

from flask import Blueprint, request
from flask_jwt_extended import jwt_required, get_jwt_identity, get_jwt

from app import db
from app.models.reader import Reader

readers = Blueprint('readers', __name__, url_prefix='/readers')

EMAIL_PATTERN = r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$'


@readers.route('', methods=['PUT'])
@jwt_required()
def update_reader():
    user_id = get_jwt_identity()
    username = request.json.get('username')
    password = request.json.get('password')
    email = request.json.get('email')
    phone = request.json.get('phone')

    reader = Reader.query.get(user_id)
    if username:
        reader.username = username
    if password:
        reader.password = password
    if email:
        if not re.match(EMAIL_PATTERN, email):
            return {
                'error': 'Invalid email format!'
            }, 400
        reader.email = email
    if email:
        reader.phone = phone
    db.session.commit()
    return '', 204


@readers.route('', methods=['GET'])
@jwt_required()
def get_reader():
    user_id = get_jwt_identity()
    reader = Reader.query.get(user_id)
    return {
        'userId': reader.user_id,
        'username': reader.username,
        'email': reader.email,
        'phone': reader.phone
    }, 200


@readers.route('', methods=['DELETE'])
@jwt_required()
def delete_reader():
    user_id = get_jwt_identity()
    reader = Reader.query.get(user_id)
    db.session.delete(reader)
    db.session.commit()
    return '', 204


@readers.route('/list', methods=['GET'])
@jwt_required()
def get_all_readers():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per-page', 10, type=int)
    reader_list = Reader.query.paginate(page=page, per_page=per_page, error_out=False)
    return {
        'total': reader_list.total,
        'page': reader_list.page,
        'perPage': reader_list.per_page,
        'items': [
            {
                'userId': reader.user_id,
                'username': reader.username,
                'email': reader.email,
                'phone': reader.phone
            } for reader in reader_list.items
        ]
    }, 200


@readers.route('/user-id/<user_id>', methods=['GET'])
def if_reader_exist(user_id):
    if Reader.query.get(user_id):
        return '', 204
    else:
        return '', 404


@readers.route('/manage/<user_id>', methods=['GET'])
@jwt_required()
def get_a_reader_info(user_id):
    claims = get_jwt()
    role = claims['role']
    if role == 0:
        return {
            'error': 'No access!'
        }, 403

    reader = Reader.query.get(user_id)
    return {
        'userId': reader.user_id,
        'username': reader.username,
        'email': reader.email,
        'phone': reader.phone
    }, 200


@readers.route('/manage/<user_id>', methods=['DELETE'])
@jwt_required()
def delete_a_reader(user_id):
    claims = get_jwt()
    role = claims['role']
    if role == 0:
        return {
            'error': 'No access!'
        }, 403

    admin_id = get_jwt_identity()
    if admin_id == user_id:
        return {
            'error': 'You cannot delete yourself!'
        }, 400

    reader = Reader.query.get(user_id)
    db.session.delete(reader)
    db.session.commit()
    return '', 204


@readers.route('/manage/<user_id>', methods=['PUT'])
@jwt_required()
def update_a_reader(user_id):
    claims = get_jwt()
    role = claims['role']
    if role == 0:
        return {
            'error': 'No access!'
        }, 403

    username = request.json.get('username')
    password = request.json.get('password')
    email = request.json.get('email')
    phone = request.json.get('phone')

    reader = Reader.query.get(user_id)
    if username:
        reader.username = username
    if password:
        reader.password = password
    if email:
        if not re.match(EMAIL_PATTERN, email):
            return {
                'error': 'Invalid email format!'
            }, 400
        reader.email = email
    if phone:
        reader.phone = phone
    db.session.commit()
    return '', 204
